package com.ruoyi.bizsys.service.impl;

import java.beans.Transient;
import java.math.BigDecimal;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.bizsys.domain.ApplyAppData;
import com.ruoyi.bizsys.domain.ProductInfo;
import com.ruoyi.bizsys.mapper.ApplyAppDataMapper;
import com.ruoyi.bizsys.service.IApplyAppDataService;
import com.ruoyi.bizsys.service.IIncreasedLimitLogService;
import com.ruoyi.bizsys.vo.IncreasedLimitLogVo;
import com.ruoyi.common.constant.LoanConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.bizsys.mapper.CreditAccountMapper;
import com.ruoyi.bizsys.domain.CreditAccount;
import com.ruoyi.bizsys.service.ICreditAccountService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 账户信息Service业务层处理
 *
 * @author african-loan
 * @date 2021-03-15
 */
@Slf4j
@Service
@AllArgsConstructor
public class CreditAccountServiceImpl extends ServiceImpl<CreditAccountMapper, CreditAccount> implements ICreditAccountService {

    private CreditAccountMapper creditAccountMapper;

    private RedisCache redisCache;

    RedissonClient redissonClient;

    private IIncreasedLimitLogService increasedLimitLogService;

    /**
     * 查询账户信息
     *
     * @param id 账户信息ID
     * @return 账户信息
     */
    @Override
    public CreditAccount selectCreditAccountById(Long id) {
        return creditAccountMapper.selectCreditAccountById(id);
    }

    /**
     * 查询账户信息列表
     *
     * @param creditAccount 账户信息
     * @return 账户信息
     */
    @Override
    public List<CreditAccount> selectCreditAccountList(CreditAccount creditAccount) {
        return creditAccountMapper.selectCreditAccountList(creditAccount);
    }

    /**
     * 新增账户信息
     *
     * @param creditAccount 账户信息
     * @return 结果
     */
    @Override
    public int insertCreditAccount(CreditAccount creditAccount) {
        creditAccount.setCreateTime(DateUtils.getNowDate());
        return creditAccountMapper.insertCreditAccount(creditAccount);
    }

    /**
     * 修改账户信息
     *
     * @param creditAccount 账户信息
     * @return 结果
     */
    @Override
    public int updateCreditAccount(CreditAccount creditAccount) {
        creditAccount.setUpdateTime(DateUtils.getNowDate());
        return creditAccountMapper.updateCreditAccount(creditAccount);
    }

    /**
     * 批量删除账户信息
     *
     * @param ids 需要删除的账户信息ID
     * @return 结果
     */
    @Override
    public int deleteCreditAccountByIds(Long[] ids) {
        return creditAccountMapper.deleteCreditAccountByIds(ids);
    }

    /**
     * 删除账户信息信息
     *
     * @param id 账户信息ID
     * @return 结果
     */
    @Override
    public int deleteCreditAccountById(Long id) {
        return creditAccountMapper.deleteCreditAccountById(id);
    }

    @Override
    public List<CreditAccount> getOverflowAmount() {
        return creditAccountMapper.getOverflowAmount();
    }

    @Override
    public void updateOverflowAmount(String custNo, BigDecimal overFlowAmount) {
        creditAccountMapper.updateOverflowAmount(custNo, overFlowAmount);
    }

    @Override
    public void updateFrozenCreditAccount(String custNo, BigDecimal frozenOverFlowAmount) {
        creditAccountMapper.updateFrozenCreditAccount(custNo, frozenOverFlowAmount);
    }

    @Override
    public void updateOverflow(String custNo, BigDecimal overFlowAmount, BigDecimal frozenOverFlowAmount) {
        creditAccountMapper.updateOverflow(custNo, overFlowAmount, frozenOverFlowAmount);
    }

    public CreditAccount findInCustNos(String custNo) {
        return getOne(new QueryWrapper<CreditAccount>().eq("cust_no", custNo));
    }

    @Transactional
    public int updateCreditLine(BigDecimal raiseLimit, String customerNo, String adjustType) {
        log.info("客户{}开始更新账户", customerNo);
        String lockKey = LoanConstants.CUST_ACCOUNT_LOCK_KEY_PREFIX + customerNo;
        RLock lock = redisCache.lock(lockKey);
        try {
            long start = System.currentTimeMillis();
            //更新授信账户
            CreditAccount account = findInCustNos(customerNo);
            CreditAccount accountNew = new CreditAccount();
            accountNew.setId(account.getId());
            accountNew.setCreditLine(account.getCreditLine().add(raiseLimit));
            if (updateCreditAccount(accountNew) > 0) {
                //新增提额日志
                IncreasedLimitLogVo increasedLimitLogVo = new IncreasedLimitLogVo(customerNo, account.getCreditLine(), raiseLimit, adjustType);
                return increasedLimitLogService.insertIncreasedLimitLog(increasedLimitLogVo);
            }
            log.info("客户{}提额更新账户结束", customerNo);
            long end = System.currentTimeMillis();
            log.info("锁占用时间，耗时：" + (end - start) + " ms");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return -1;
    }

    @Override
    public BigDecimal getLatestQuota(String custNo) {
        QueryWrapper<CreditAccount> queryWrapper = new QueryWrapper<CreditAccount>().eq("cust_no", custNo).select("credit_line");
        return this.getOne(queryWrapper).getCreditLine();
    }

    @Override
    public CreditAccount getNormalAcountOnLoan(String custNo) {
        return creditAccountMapper.getNormalAcountOnLoan(custNo);
    }

    @Override
    public boolean unfreezeQuota(String custNo, BigDecimal unfreezeQuota) {
        return creditAccountMapper.unfreezeQuota(custNo, unfreezeQuota) > 0;
//        QueryWrapper<CreditAccount> queryWrapper = new QueryWrapper<CreditAccount>().eq("cust_no", custNo);
//        CreditAccount creditAccount = getOne(queryWrapper);
//        //已冻结额度减去需解除额度
//        BigDecimal frozenQuota = creditAccount.getFrozenQuota().subtract(unfreezeQuota).doubleValue() <= 0 ? BigDecimal.ZERO : creditAccount.getFrozenQuota().subtract(unfreezeQuota);
//        UpdateWrapper<CreditAccount> up = new UpdateWrapper<CreditAccount>().set("frozen_quota", frozenQuota).eq("id", creditAccount.getId());
//        return update(up);
    }

    @Override
    public int updateFrozenQuota(String custNo, BigDecimal frozenQuota) {
        return creditAccountMapper.updateFrozenQuota(custNo, frozenQuota);
    }

    @Override
    public void updateCreditAccountRest(CreditAccount creditAccount) {
        baseMapper.updateCreditAccountRest(creditAccount);
    }
    @Override
    public boolean isCredit(String custNo) {
        return count(new QueryWrapper<CreditAccount>().eq("cust_no", custNo)) > 0;
    }

    @Override
    public List<ProductInfo> selectCreditAccountProduct(String custNo) {
        return creditAccountMapper.selectCreditAccountProduct(custNo);
    }

    @Override
    public List<CreditAccount> getOnLoanCreditAccountsHasCard() {
        return baseMapper.getOnLoanCreditAccountsHasCard();
    }

    @Override
    public CreditAccount getByCustNo(String custNo) {
        return getOne(new QueryWrapper<CreditAccount>().eq("cust_no", custNo));
    }


}
